package com.zlll.winner.service.common;

import com.zlll.winner.business.service.common.IRedisService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.nio.charset.Charset;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class RedisServiceImpl implements IRedisService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private RedisTemplate redisTemplate;

    private final Charset CODE = Charset.forName("UTF-8");

    @Autowired(required = false)
    public void setRedisTemplate(StringRedisTemplate redisTemplate) {
        RedisSerializer stringSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setValueSerializer(stringSerializer);
        redisTemplate.setHashKeySerializer(stringSerializer);
        redisTemplate.setHashValueSerializer(stringSerializer);
        this.stringRedisTemplate = redisTemplate;
    }

    @Override
    public void setRedisByString(String key,String value,Integer outTime) {
        stringRedisTemplate.delete(key);
        stringRedisTemplate.opsForValue().set(key,value, outTime, TimeUnit.SECONDS);
    }

    @Override
    public String getRedisByString(String key) {
        return stringRedisTemplate.opsForValue().get(key);
    }

    @Override
    public void deteleRedisByString(String key) {
        stringRedisTemplate.delete(key);
    }

    @Override
    public void deteleByCollectionString(List<String> key) {
        stringRedisTemplate.delete(key);
    }

    @Override
    public void setKeyLifeCycle(String key, int seconds) {
        stringRedisTemplate.expire(key,seconds,TimeUnit.SECONDS);
    }

    @Override
    public  Long incr(String key, long add) {
        return (Long) redisTemplate.execute((RedisCallback<Long>) con -> {
            Long record = con.incrBy(toBytes(key), add);
            return record == null ? 0L : record;
        });
    }

    private void nullCheck(Object... args) {
        for (Object obj : args) {
            if (obj == null) {
                throw new IllegalArgumentException("redis argument can not be null!");
            }
        }
    }

    private  byte[] toBytes(String key) {
        nullCheck(key);
        return key.getBytes(CODE);
    }
}
